package com.strategy.aspect;


import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import com.strategy.utils.JsonUtils;
import com.strategy.entity.StrategyExecuteLog;
import com.strategy.mapper.StrategyExecuteLogMapper;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 策略执行监控切面，记录执行日志和统计信息
 */
@Slf4j
@Aspect
@Component
public class StrategyMonitorAspect {

    @Resource
    private StrategyExecuteLogMapper strategyExecuteLogMapper;

    /**
     * 定义切入点：策略执行方法
     */
    @Pointcut(value = "execution(* com.strategy.manager.StrategyManager.executeStrategy(..)) && args(key, version, input, params)", argNames = "key,version,input,params")
    public void strategyExecutePointcut(String key, String version, Object input, Object params) {
    }

    /**
     * 环绕通知，记录执行时间和结果
     */
    @Around(value = "strategyExecutePointcut(key, version, input, params)", argNames = "joinPoint,key,version,input,params")
    public Object aroundExecute(ProceedingJoinPoint joinPoint, String key, String version, Object input, Object params) throws Throwable {
        StrategyExecuteLog logEntity = new StrategyExecuteLog();
        logEntity.setStrategyKey(key);
        logEntity.setVersion(version);
        logEntity.setCreateTime(LocalDateTime.now());

        // 记录入参
        try {

            logEntity.setInputParams(JsonUtils.toJsonString(input));
        } catch (Exception e) {
            log.warn("序列化输入参数失败", e);
            logEntity.setInputParams("参数序列化失败");
        }

        long startTime = System.currentTimeMillis();
        Object result;
        try {
            // 执行策略
            result = joinPoint.proceed();
            logEntity.setStatus(1); // 成功
            logEntity.setResult(JsonUtils.toJsonString(result));
            return result;
        } catch (Exception e) {
            logEntity.setStatus(0); // 失败
            logEntity.setErrorMsg(e.getMessage());
            throw e;
        } finally {
            // 记录执行时间
            long endTime = System.currentTimeMillis();
            logEntity.setExecuteTime(endTime - startTime);

            // 保存日志
            try {
                strategyExecuteLogMapper.insert(logEntity);
            } catch (Exception e) {
                log.error("保存策略执行日志失败", e);
            }
        }
    }
}